// Lindsay Gilmour
// Adam Lusch
// Dan Niceswanger
//
// Computer Graphics Project 1:
// Asteroids!
// A Tribute

#include <GL/glut.h>

#include <Box2D.h>
#include "PhysicsWorld.h"

namespace
{
	int32 width = 800;
	int32 height = 600;
	int32 framePeriod = 16;
	float32 timeStep = 1.0 / 60.0;
	int32 iterations = 10;
	b2Vec2 viewCenter(0.0f, 0.0f);
	PhysicsWorld pworld;
	int32 keys[256];
	int32 bulletCounter = 0;
	int32 bulletWait = 7;
}

void resize(int32 w, int32 h)
{
	width = w;
	height = h;

	glViewport(0, 0, w, h);

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();

	float32 ratio = float32(w) / float32(h);
	b2Vec2 extents(ratio * 25.0f, 25.0f);

	b2Vec2 lower = viewCenter - extents;
	b2Vec2 upper = viewCenter + extents;

	pworld.setViewable(lower.x, upper.x, lower.y, upper.y);

	// L/R/B/T
	gluOrtho2D(lower.x, upper.x, lower.y, upper.y);
}

// This is used to control the frame rate (60Hz).
void timer(int)
{
	glutPostRedisplay();
	glutTimerFunc(framePeriod, timer, 0);
}

void simulationLoop()
{	 
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	pworld.step(timeStep, iterations, keys);
	
	if (bulletCounter != 0)
	{
		bulletCounter++;
		bulletCounter %= bulletWait;
	}

	glutSwapBuffers();
}

// change the keyState to include the
// direction of the pressed key
void pressArrowKey(int k, int, int)
{
	switch (k)
	{
		case GLUT_KEY_LEFT:
			keys[k] = 1;
			break;
		case GLUT_KEY_RIGHT:
			keys[k] = 1;
			break;
		case GLUT_KEY_UP:
			keys[k] = 1;
			break;
		default:
			break;
	}
}

// tell keyState to remove the direction of
// the key which was just released
void releaseArrowKey(int k, int, int)
{
	switch (k)
	{
		case GLUT_KEY_LEFT:
			keys[k] = 0;
			//cout << "Left key was released" << ", keystate: " << keyState << endl;
			break;
		case GLUT_KEY_RIGHT:
			keys[k] = 0;
			//cout << "Right key was released" << ", keystate: " << keyState << endl;
			break;
		case GLUT_KEY_UP:
			keys[k] = 0;
			//cout << "Up key was released" << ", keystate: " << keyState << endl;
			break;
		default:
			break;
	}
}

void keyPressed(unsigned char k, int, int)
{
	if (pworld.isScoring() )
	{
		pworld.addLetter(k);
	}
	switch(k)
	{
		case ' ':
			if (pworld.isPlaying())
			{
				if (bulletCounter == 0)
				{
					bulletCounter = 1;
					pworld.spawnBullet();
				}
			}
			else
			{
				pworld.startGame();
			}
			break;
		case 'h':
			pworld.getScores();
			break;
		case 27:	// ESC key
			pworld.splashScreen();
			break;
	}
}

// This is a simple example of building and running a simulation
// using Box2D. Here we create a large ground box and a small dynamic
// box.
int main(int argc, char** argv)
{
	time_t seed = time(0);
	srand(seed);
	//cout << "Seeding with " << seed << endl;

	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
	;
	glutInitWindowSize(width, height);
	glutCreateWindow("Asteroids! A Tribute");

	glutReshapeFunc(resize);
	glutDisplayFunc(simulationLoop);
	glutTimerFunc(framePeriod, timer, 0);
	glutSpecialFunc(pressArrowKey);
	glutSpecialUpFunc(releaseArrowKey);
	glutKeyboardFunc(keyPressed);

	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glEnable(GL_LINE_SMOOTH);
	glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);

	pworld.init();
	pworld.splashScreen();

	glutMainLoop();

	return 0;
}
